package net.zoneland.knowledge.model;

import java.io.Serializable;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import net.zoneland.knowledge.enums.AttachTypeEnum;
import org.apache.commons.lang.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.annotation.JsonFormat;

import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.enums.ProcessStateEnum;
import net.zoneland.knowledge.enums.WorkSubTaskNodeEnum;

/**
 * 工单子任务信息.
 *
 * @author zmq
 * @Date 2022/8/9 9:23
 */
public class WorkSubTaskInfo implements Serializable {
    private static final long serialVersionUID = -6544667605241584814L;
    /**
     * 主键.
     */
    private String id;
    /**
     * 子任务名称.
     */
    private String name;
    /**
     * 任务描述.
     */
    private String description;
    /**
     * 责任部门dn，";"分隔.
     */
    private String deptDns;
    /**
     * 责任部门名称，";"分隔.
     */
    private String deptNames;
    /**
     * 要求完成日期.
     */
    @JsonFormat(pattern = Constants.DATE_TIME_FORMAT_WITH_MINUTE, timezone = "GMT+8")
    @DateTimeFormat(pattern = Constants.DATE_TIME_FORMAT_WITH_MINUTE)
    private Date finishTime;
    /**
     * 工单主键id.
     */
    private String workApplyId;
    /**
     * 父工单id.
     */
    private String parentWorkApplyId;
    /**
     * 父任务id.
     */
    private String parentTaskId;
    /**
     * 主分任务id，指最顶层的分任务id，不管分派（拆分）多少次，主任务id永远不变。
     */
    private String mainTaskId;

    /**
     * 流程环节.
     */
    private WorkSubTaskNodeEnum node;
    /**
     * 流程状态.
     */
    private ProcessStateEnum state;
    /**
     * 要求完成日期.
     */
    @JsonFormat(pattern = Constants.DATE_TIME_FORMAT_DEFAULT, timezone = "GMT+8")
    @DateTimeFormat(pattern = Constants.DATE_FORMAT_DEFAULT)
    private Date updateTime;

    /**
     * 模板附件信息.
     */
    private List<WorkApplyInfoAttachment> templateAttachments;

    /**
     * 合并报表附件信息.
     */
    private List<WorkApplyInfoAttachment> mergeAttachments;
    /**
     * 工单处理结果附件(上报附件).
     * <p>
     * 暂时要求是excel类型的附件.
     * </p>
     */
    private List<WorkApplyInfoAttachment> reportAttachments;

    /**
     * 排序用的索引号。
     */
    private int orderIndex;

    /**
     * 是否是新增的，这个字段不需要保存，用来前后端交互时的标记。
     */
    private boolean newAdd;

    /**
     * 是否上报合并报表。
     */
    private boolean reportMergeAttachment;

    /**
     * 上报次数.
     * 上报次数会影响附件合并行为.
     */
    private int reportCount;

    /**
     * 是否采用共享编辑.
     * 默认不采用
     */
    private boolean applySharedEditing = false;

    /**
     * 是否自动合并附件.
     * 默认需要合并
     */
    private boolean autoMergeAttachment = true;

    /**
     * 合并附件时，是否合并处理人
     * 默认合并处理人
     */

    private boolean removeHandler = true;

    public boolean isRemoveHandler() {
        return removeHandler;
    }

    public void setRemoveHandler(boolean removeHandler) {
        this.removeHandler = removeHandler;
    }

    /**
     * 业务方法，返回node的中文名.
     * @return 当前环节所对应的中文名
     */
    public String getNodeName() {
        return Optional.ofNullable(node).map(WorkSubTaskNodeEnum::getNodeName).orElse(StringUtils.EMPTY);
    }

    /**
     * 业务方法，清空所有附件.
     */
    public void clearAllAttachment() {
        templateAttachments = Collections.emptyList();
        mergeAttachments = Collections.emptyList();
        reportAttachments = Collections.emptyList();
    }

    /**
     * 获取 模板附件信息.
     *
     * @return 模板附件信息
     */
    public List<WorkApplyInfoAttachment> getTemplateAttachments() {
        return templateAttachments;
    }

    /**
     * 设置 模板附件信息.
     *
     * @param templateAttachments 模板附件信息
     */
    public void setTemplateAttachments(List<WorkApplyInfoAttachment> templateAttachments) {
        this.templateAttachments = templateAttachments;
    }

    /**
     * 获取 合并报表附件信息.
     *
     * @return 合并报表附件信息
     */
    public List<WorkApplyInfoAttachment> getMergeAttachments() {
        return mergeAttachments;
    }

    /**
     * 设置 合并报表附件信息.
     *
     * @param mergeAttachments 合并报表附件信息
     */
    public void setMergeAttachments(List<WorkApplyInfoAttachment> mergeAttachments) {
        this.mergeAttachments = mergeAttachments;
    }

    /**
     * 获取 上报附件.
     *
     * @return 上报附件
     */
    public List<WorkApplyInfoAttachment> getReportAttachments() {
        return reportAttachments;
    }

    /**
     * 设置 上报附件.
     *
     * @param reportAttachments 上报附件
     */
    public void setReportAttachments(final List<WorkApplyInfoAttachment> reportAttachments) {
        this.reportAttachments = reportAttachments;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public String getWorkApplyId() {
        return workApplyId;
    }

    /**
     * 设置 属性值.
     *
     * @param workApplyId 属性值
     */
    public void setWorkApplyId(final String workApplyId) {
        this.workApplyId = workApplyId;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public String getId() {
        return id;
    }

    /**
     * 设置 属性值.
     *
     * @param id 属性值
     */
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public String getName() {
        return name;
    }

    /**
     * 设置 属性值.
     *
     * @param name 属性值
     */
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public String getDescription() {
        return description;
    }

    /**
     * 设置 属性值.
     *
     * @param description 属性值
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public String getDeptDns() {
        return deptDns;
    }

    /**
     * 设置 属性值.
     *
     * @param deptDns 属性值
     */
    public void setDeptDns(final String deptDns) {
        this.deptDns = deptDns;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public String getDeptNames() {
        return deptNames;
    }

    /**
     * 设置 属性值.
     *
     * @param deptNames 属性值
     */
    public void setDeptNames(final String deptNames) {
        this.deptNames = deptNames;
    }

    /**
     * 获取 属性值.
     *
     * @return 属性值
     */
    public Date getFinishTime() {
        return Optional.ofNullable(finishTime).map(it -> (Date) it.clone()).orElse(null);
    }

    /**
     * 设置 属性值.
     *
     * @param finishTime 属性值
     */
    public void setFinishTime(final Date finishTime) {
        this.finishTime = Optional.ofNullable(finishTime).map(it -> (Date) it.clone()).orElse(null);
    }

    /**
     * Gets the value of parentWorkApplyId.
     *
     * @return the value of parentWorkApplyId
     */
    public String getParentWorkApplyId() {
        return parentWorkApplyId;
    }

    /**
     * Sets the parentWorkApplyId.
     *
     * @param parentWorkApplyId parentWorkApplyId
     */
    public void setParentWorkApplyId(final String parentWorkApplyId) {
        this.parentWorkApplyId = parentWorkApplyId;
    }

    /**
     * Gets the value of parentTaskId.
     *
     * @return the value of parentTaskId
     */
    public String getParentTaskId() {
        return parentTaskId;
    }

    /**
     * Sets the parentTaskId.
     *
     * @param parentTaskId parentTaskId
     */
    public void setParentTaskId(final String parentTaskId) {
        this.parentTaskId = parentTaskId;
    }

    /**
     * Gets the value of mainTaskId.
     *
     * @return the value of mainTaskId
     */
    public String getMainTaskId() {
        return mainTaskId;
    }

    /**
     * Sets the mainTaskId.
     *
     * @param mainTaskId mainTaskId
     */
    public void setMainTaskId(final String mainTaskId) {
        this.mainTaskId = mainTaskId;
    }

    /**
     * Gets the value of node.
     *
     * @return the value of node
     */
    public WorkSubTaskNodeEnum getNode() {
        return node;
    }

    /**
     * Sets the node.
     *
     * @param node node
     */
    public void setNode(final WorkSubTaskNodeEnum node) {
        this.node = node;
    }

    /**
     * Gets the value of state.
     *
     * @return the value of state
     */
    public ProcessStateEnum getState() {
        return state;
    }

    /**
     * Sets the state.
     *
     * @param state state
     */
    public void setState(final ProcessStateEnum state) {
        this.state = state;
    }

    /**
     * Gets the value of updateTime.
     *
     * @return the value of updateTime
     */
    public Date getUpdateTime() {
        return updateTime;
    }

    /**
     * Sets the updateTime.
     *
     * @param updateTime updateTime
     */
    public void setUpdateTime(final Date updateTime) {
        this.updateTime = updateTime;
    }

    /**
     * Gets the value of orderIndex.
     *
     * @return the value of orderIndex
     */
    public int getOrderIndex() {
        return orderIndex;
    }

    /**
     * Sets the orderIndex.
     *
     * @param orderIndex orderIndex
     */
    public void setOrderIndex(final int orderIndex) {
        this.orderIndex = orderIndex;
    }

    /**
     * 是否本次操作新增的分任务。
     * @return 是否本次操作新增的分任务
     */
    public boolean isNewAdd() {
        return newAdd;
    }

    /**
     * 是否本次操作新增的分任务。
     * @param newAdd 是否本次操作新增的分任务。
     */
    public void setNewAdd(final boolean newAdd) {
        this.newAdd = newAdd;
    }

    /**
     * 是否上报合并报表。
     * @return 是否上报合并报表
     */
    public boolean isReportMergeAttachment() {
        return reportMergeAttachment;
    }

    /**
     * 设置是否上报合并报表。
     * @param reportMergeAttachment 是否上报合并报表
     */
    public void setReportMergeAttachment(final boolean reportMergeAttachment) {
        this.reportMergeAttachment = reportMergeAttachment;
    }

    /**
     * 获取 reportCount.
     *
     * @return reportCount
     */
    public int getReportCount() {
        return reportCount;
    }

    /**
     * 设置 reportCount.
     *
     * @param reportCount reportCount
     */
    public void setReportCount(int reportCount) {
        this.reportCount = reportCount;
    }

    /**
     * 获取 autoMergeAttachment.
     *
     * @return autoMergeAttachment
     */
    public boolean isAutoMergeAttachment() {
        return autoMergeAttachment;
    }

    /**
     * 设置 autoMergeAttachment.
     *
     * @param autoMergeAttachment autoMergeAttachment
     */
    public void setAutoMergeAttachment(boolean autoMergeAttachment) {
        this.autoMergeAttachment = autoMergeAttachment;
    }

    /**
     * 初始化附件信息.
     * @param attachTypeEnumListMap 附件类型及信息列表
     */
    public void initAttachment(final Map<AttachTypeEnum, List<WorkApplyInfoAttachment>> attachTypeEnumListMap) {
        this.setTemplateAttachments(attachTypeEnumListMap.getOrDefault(AttachTypeEnum.TEMPLATE, Collections.EMPTY_LIST));
        this.setReportAttachments(attachTypeEnumListMap.getOrDefault(AttachTypeEnum.RESULT, Collections.EMPTY_LIST));
        this.setMergeAttachments(attachTypeEnumListMap.getOrDefault(AttachTypeEnum.MERGE, Collections.EMPTY_LIST));
    }

    /**
     * 初始化结果附件信息.
     * @param attachTypeEnumListMap 附件类型及信息列表
     */
    public void initResultAttachment(final Map<AttachTypeEnum, List<WorkApplyInfoAttachment>> attachTypeEnumListMap) {
        this.setReportAttachments(attachTypeEnumListMap.getOrDefault(AttachTypeEnum.RESULT, Collections.EMPTY_LIST));
    }

    /**
     * 获取 是否采用共享编辑.      默认不采用
     *
     * @return applySharedEditing 是否采用共享编辑.      默认不采用
     */
    public boolean isApplySharedEditing() {
        return this.applySharedEditing;
    }

    /**
     * 设置 是否采用共享编辑.      默认不采用
     *
     * @param applySharedEditing 是否采用共享编辑.      默认不采用
     */
    public void setApplySharedEditing(final boolean applySharedEditing) {
        this.applySharedEditing = applySharedEditing;
    }
}
